using System;
using System.Net;
using System.IO;
using System.Collections.Generic;

// Factory pattern
// http://en.wikipedia.org/wiki/Factory_method_pattern
// MVC pattern - Controller component
// http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
static class ReactionFactory
{
    public static IReaction Exit { get; private set; }

    static ReactionFactory() {
        Exit = new ExitReaction();



    }
    public static IReaction GetReaction(HttpListenerRequest request, Exception ex) {
        var msg = request.RawUrl + "\n" + ex;
        var reaction = new ErrorReaction(msg + "");
        return reaction;
    }

    public static IReaction GetReaction(HttpListenerRequest request) {

        IReaction ret;

        // "/index.html"
        var url_path_component = request.Url.LocalPath;

        if (url_path_component == "/dispatch") {
            // form submit button

            ret = GetReactionFromButton(request);

        }
        else {
            // regular url request

            ret = GetReactionFromPath(url_path_component, request);

        }

        return ret;

    }

    static string GetSubmitButtonParam(HttpListenerRequest request) {
        foreach (string str in request.QueryString.Keys) {
            if (str.StartsWith(Program.query_submit_prefix)) {
                return str;
            }
        }

        return null;
    }

    static IReaction CreateStaticReactionFromUrlPathComponent(string url_path_component) {
        if (!System.IO.File.Exists(Helpers.GetPathFromUrlPathComponent(url_path_component))) {
            return null;
        }
        return new StaticReaction(url_path_component);
    }

    public static ProgramReaction GetProgramReaction(HttpListenerRequest request) {
        var index = int.Parse(request.QueryString[Program.query_index] ?? "0") + 1;
        var free_time = new FreeTime();

        return new ProgramReaction(Program.page_program, request.GetProfileParam(), index, free_time);
    }

    public static IReaction GetReactionFromPath(string url_path_component, HttpListenerRequest request) {

        var path = Helpers.TrimUrlPathComponent(url_path_component);

        if (path == Program.page_start) {
            return new IndexReaction(url_path_component);
        }

        if (path == Program.page_create) {
            return new CreateReaction(url_path_component);
        }

        if (path == Program.page_program) {
            return GetProgramReaction(request);

        }

        if (path == Program.page_edit_program) {
            return new EditProgramReaction(Program.page_edit_program, request.GetProfileParam());

        }

        // css
        var static_reaction = CreateStaticReactionFromUrlPathComponent(url_path_component);
        if (static_reaction != null) {
            return static_reaction;
        }

        return new ErrorReaction(url_path_component, HttpStatusCode.NotFound);

    }

    static Dictionary<string, string> GetQueryStringDictionary(HttpListenerRequest request) {
        var ret = new Dictionary<string, string>();
        foreach (string key in request.QueryString.Keys) {
            ret.Add(key, request.QueryString[key] + "");
        }
        return ret;
    }

    public static IReaction GetReactionFromButton(HttpListenerRequest request) {

        string button = GetSubmitButtonParam(request);
        // may be null
        string profile = request.GetProfileParam();
        var name = request.QueryString[Program.query_name];
        var dict = GetQueryStringDictionary(request);

        if (button == Program.submit_index_exit) {

            return Exit;

        }

        if (button == Program.submit_index_create) {

            // todo
            return new RedirectReaction(Program.page_create);

        }

        if (button == Program.submit_create_accept) {


            profile = Helpers.GetProfileFromName(name);


            Helpers.InitProfile(name, profile, dict);

            dict[Program.query_profile] = profile;

            return new RedirectReaction(Program.page_edit_program, dict);

        }

        if (button == Program.submit_index_login) {

            profile = Helpers.GetProfileFromName(name);
            dict[Program.query_profile] = profile;
            return new RedirectReaction(Program.page_edit_program, dict);


        }
        if (button == Program.submit_edit_accept) {

            // todo: logic
            return new RedirectReaction(Program.page_program, dict);

        }

        if (button == Program.submit_program_main ||
            button == Program.submit_edit_cancel) {

            return new RedirectReaction(Program.page_start);

        }

        if (button == Program.submit_program_new) {

            return new RedirectReaction(Program.page_program, GetQueryStringDictionary(request));

        }


        throw new ArgumentException("button = " + button);
    }
}

